{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Transmission Line Losses on a Loaded Lossy Line "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When dealing with RF power, for instance in radio, industry or scientific applications, a recurrent problem is to handle the inevitable RF losses correctly to avoid overheating of cables and components. \n",
    "\n",
    "## Matched Load\n",
    "In this example, we will use `scikit-rf` to evaluate the losses in a 50 Ohm, 20 meters long, RG-8 cable (VF=0.84) charged with a resistive load $R_L=50\\Omega$ at 13.56 MHz. The cable losses are estimated to 1.483 dB/100 meters and the source power to 400W. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, the usual Python imports:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import skrf as rf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rf.stylely()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's define the problem constants:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Pin = 400  # W\n",
    "z0 = 50 # Ohm\n",
    "freq = rf.Frequency(13.56, npoints=1, unit='MHz')\n",
    "VF = 0.84\n",
    "RL = 50  # Ohm\n",
    "L = 20  # m"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The propagation constant of the transmission line $\\gamma=\\alpha+j\\beta$ is: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "alpha = rf.db_2_np(1.483/100)  # Np/m\n",
    "beta = freq.w/rf.c/VF\n",
    "gamma = alpha + 1j*beta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The matched line loss (or power attenuation), $a=e^{2\\alpha L}$, is: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.exp(2*alpha*L)  # also simply 2.84/100*20\n",
    "print('Matched line loss: a=', rf.mag_2_db10(a), 'dB')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the line is charged with a matched load, ie. $R_L=50\\Omega$, then the total line loss is $a$. The power lost in the cable will thus be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('(Forward) Power delivered to the  load:', Pin/a, 'W')\n",
    "print('Power lost in the cable:', Pin *( 1 - 1/a), 'W')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which can also be checked by the `scikit-rf` transmission line function `zl_2_total_loss`: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a_skrf = rf.zl_2_total_loss(z0, zl=RL, theta=gamma*L)\n",
    "print('Power lost in the cable:',\n",
    "      Pin * (1 - 1/a_skrf), 'W')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another way to evaluate the total power dissipated in the circuit is to evaluate the power expression:\n",
    "\n",
    "$$\n",
    "P_{delivered} = \\frac{1}{2} \\Re \\left[ V I^* \\right]\n",
    "$$\n",
    "\n",
    "where $V$ and $I$ are the (peak) total voltage and current. They can be evaluate using the transmission line function `voltage_current_propagation`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# reflection coefficient and input impedance\n",
    "Gamma_in = rf.zl_2_Gamma_in(z0, RL, theta=gamma*L)\n",
    "Z_in = rf.zl_2_zin(z0, RL, theta=gamma*L)\n",
    "\n",
    "# voltage and current at the line input as a function of source power \n",
    "V_in = np.sqrt(2*z0*Pin)*(1 + Gamma_in)\n",
    "I_in = V_in/Z_in\n",
    "\n",
    "# voltage and current at z=L\n",
    "V,I = rf.voltage_current_propagation(V_in, I_in, z0, gamma*L)\n",
    "P_delivered = 1/2 * np.real(V * np.conj(I))\n",
    "print('Power delivered to the load: ', P_delivered, 'W')\n",
    "print('Power dissipated in the cable: ',Pin - P_delivered, 'W')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Non Matched load"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, if the load is not perfectly matched to the line characteristic impedance $z_0$, for example with $R_L=200 + 30j\\Omega$, additional losses are induced by the reflected wave. The reflection coefficient $\\Gamma_{load}$ induced by this load is:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z0 = 50\n",
    "ZL = 200 - 30j\n",
    "Gamma_load = rf.zl_2_Gamma0(z0, ZL)\n",
    "print('|Gamma_load|=', np.abs(Gamma_load))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "while the reflection coefficient seen at the input of the transmission line $\\Gamma_{in}$ is: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Gamma_in = rf.zl_2_Gamma_in(z0, ZL, theta=gamma*L) \n",
    "SWR = rf.Gamma0_2_swr(rf.zl_2_Gamma_in(z0, ZL, theta=gamma*L))\n",
    "print('|Gamma_in|=', np.abs(Gamma_in), '(SWR=', SWR,')')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The total loss in dB due to SWR is often stated as:\n",
    "$$\n",
    "a_{[dB]} + 10 \\log_{10} \\frac{1 - |\\Gamma_{in}|^2}{1 - |\\Gamma_{load}|^2}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "10*np.log10(a) + 10*np.log10((1 - np.abs(Gamma_in)**2)/(1 - np.abs(Gamma_load)**2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, this expression is only correct if either properties are verified:\n",
    "- (i) the characteristic impedance of the line is real (distorsionless line) \n",
    "- (ii) reflection coefficient is real (ie real $Z_L/Z_0$) [1]. \n",
    "\n",
    "The 1st condition is met here, however it will not be the case in the next section. \n",
    "\n",
    "Anyway, the `scikit-rf` transmission line function `zl_2_total_loss` is correct in all conditions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = rf.zl_2_total_loss(z0, zl=ZL, theta=gamma * L)\n",
    "print('Total power loss: ', rf.mag_2_db10(a), 'dB' )\n",
    "print('Delivered power:', Pin/a, 'W')\n",
    "print('The total power loss is the cable:', Pin*(1 - 1/a), 'W')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# reflection coefficient and input impedance\n",
    "Gamma_in = rf.zl_2_Gamma_in(z0, ZL, theta=gamma*L)\n",
    "Z_in = rf.zl_2_zin(z0, ZL, theta=gamma*L)\n",
    "\n",
    "# voltage and current at the line input as a function of source power \n",
    "V_in = np.sqrt(2*z0*Pin)*(1 + Gamma_in)\n",
    "I_in = V_in/Z_in\n",
    "\n",
    "# voltage and current at z=L\n",
    "V,I = rf.voltage_current_propagation(V_in, I_in, z0, gamma*L)\n",
    "P_delivered = 1/2 * np.real(V * np.conj(I))\n",
    "print('Power delivered to the load: ', P_delivered, 'W')\n",
    "print('Power dissipated in the cable: ',Pin - P_delivered, 'W')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rf.Gamma0_2_swr(Gamma_in)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "10*np.log10(P_delivered/Pin)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## A more advanced example\n",
    "This example reproduces the example presented in reference [1].\n",
    "\n",
    "Let's assume a coaxial line ([Wireman #551, 450-Ohm](https://thewireman.com/antennap.html)) loaded with a complex load $Z_L=R_L + jX_L$, with the following parameters:  \n",
    " - line length: 100 feet\n",
    " - frequency: 1.83 MHz\n",
    " - [attenuation constant](https://en.wikipedia.org/wiki/Propagation_constant#Attenuation_constant): $\\alpha=$ 0.095 dB/100 feet\n",
    " - coaxial relative permittivity: $\\epsilon_r=1.194$ ([Velocity Factor](https://en.wikipedia.org/wiki/Velocity_factor) VF=0.915)\n",
    " - real part of the characteristic impedance: $R_0 = \\Re \\left[Z_0\\right]$=402.75 Ohm\n",
    " - Load resistance: $R_L$ = 4.5 Ohm\n",
    " - Load reactance: $X_L$ = -1673 Ohm\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Z_L = 4.5 - 1673j\n",
    "R_0 = 402.75\n",
    "freq = rf.Frequency(1.83, npoints=1, unit='MHz')\n",
    "VF = 0.915\n",
    "L = rf.feet_2_meter(100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we can derive the propagation constant $\\gamma=\\alpha+j\\beta$ with $\\beta=\\frac{\\omega}{c }\\sqrt{\\epsilon_r}$ from the problem parameters:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "alpha = rf.db_2_np(rf.db_per_100feet_2_db_per_100meter(0.095)/100)\n",
    "beta = freq.w/rf.c/VF\n",
    "gamma = alpha + 1j*beta\n",
    "print(gamma)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, the transmission line characteristic reactance is not given in the problem parameters and must be determined. It can be approximated from a high-frequency, low-loss approximation [1]:\n",
    "$$\n",
    "Z_0 = R_0 + j X_0 \\approx R_0 - j \\frac{\\alpha}{\\beta}R_0\n",
    "$$  \n",
    "ie,\n",
    "$$\n",
    "X_0 \\approx - \\frac{\\alpha}{\\beta}R_0\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_0 = -alpha/beta*R_0\n",
    "Z_0 = R_0 + 1j*X_0 \n",
    "print('X_0=', X_0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have both the characteristic impedance and the propagation constant of the line, the reflection coefficients, input impedance and total loss can be deduced: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('Gamma at load:', np.abs(rf.zl_2_Gamma0(Z_0, Z_L)))\n",
    "print('Gamma at input:', np.abs(rf.zl_2_Gamma_in(Z_0, Z_L, theta=gamma*L)))\n",
    "print('SWR at load:', rf.Gamma0_2_swr(rf.zl_2_Gamma0(Z_0, Z_L)))\n",
    "\n",
    "print('SWR at input:', rf.Gamma0_2_swr(rf.zl_2_Gamma_in(Z_0, Z_L, theta=gamma*L)))\n",
    "print('Input impedance:', rf.input_impedance_at_theta(Z_0, Z_L, theta=gamma*L ), 'Ohm')\n",
    "\n",
    "total_loss_db = rf.mag_2_db10(np.abs(rf.zl_2_total_loss(z0=Z_0, zl=Z_L, theta=gamma*L)))\n",
    "print('Total loss:', total_loss_db, 'dB')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "which match the results presented in reference [1]."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## References\n",
    " - [1] Steve Stearns (K6OIK), A Transmission Line Power Paradox and Its Resolution, ARRL Pacificon Antenna Seminar, Santa Clara, CA          October 10-12, 2014: https://www.fars.k6ya.org/docs/K6OIK-A_Transmission_Line_Power_Paradox_and_Its_Resolution.pdf\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
